昨天試了gRPC後成效不錯,可以利用雙向溝通的方式來達成配對的機制模擬。然而這幾天花了些時間了解配對時,發現文件裡的配對有特別提到可以利用PubSub的概念進行,剛好這一陣也利用Google Cloud Platfomr(GCP)進行建置的任務。就在思考是否可用Google Cloud PubSub處理。不過在這裡也記錄自己思考點的轉換。
決大多數的tcp/udp連線型的遊戲,其實是從登入時就一直保持的這樣的連線,這樣的做法是大宗表示連線遊戲這樣規劃是沒有問題的。不過我自己的想法是在多數情況下其實不用一直處於這種雙向連線,只有在遊戲主要關卡遊玩時一直維雙向連線即可,其它時間或許可以利用有需求才連線的方式進行即可。因此,在這樣的想法之下所做出來的規劃就變成多數時間都不維持雙向連線,但需求產生時要用其它的方式去處理。配對則剛好是考驗這樣架構下第一步要解決的。
嘗試gRPC,它是雙向的http2協定,利用其rpc的架構,只有在request當下和response回來前連向才是被建立的。對於Client來說,多這條連線並沒有資源使用下太大的差異,但對於server來說,不需要一直連線的情況下,對資源控管有一定的幫助。因此才想著若是配對的需求利用rpc做處理,應該可以減輕server的負擔。但再花些時間想和看到了配對library文件裡的敘述後,或許PubSub更符合配對機制的要求。
多數的配對約為數秒到2分鐘左右,其實一直用gRPC連著,可能也沒有太大的問題。利用PubSub,在概念上則是有事件傳入後再進行處理。也就是從開始要求配對的當下,直到配對成功後回傳事件,才要進行配對成功後續的處理,在概念上相當的美好。也就是想到了這層事件處理的方式後,今日才會試著用Google Cloud PubSub進行。
不過Google Cloud PubSub在Unity裡無法順利被執行,找了一些網路上的文章也沒有對如何在Unity裡使用有任何說明。我個人猜想的原因是Google Cloud PubSub會用到gRPC,但這個版本不是依據Unity做的特化版,所以無法正常的在Unity裡執行。故尋找替代品,找到了PubNub。Signup很簡單,直接用Google Account就行,而跟據最近更新的免費使用FAQ,Can I use PubNub for free?拿來做開發用不會是太大的問題。
帳號在生成時會放一個Demo App進去,直接選擇要用Unity方式進行
直接從官方在GitHub那的連結下載最新版的unitypackage,並將Dashboard下出現的程式碼,直接貼到Unity的Script裡。在Unity Editor執行後在command line利用curl(一樣是PubNub官方Demo的用法)
curl --data '{"sender": "cUrl", "content": "Hello From cURL"}' "https://ps.pndsn.com/publish/${pub-key}/${sub-key}/0/pubnub_onboarding_channel/myCallback"
則可於Debug Console裡看到訊息。
到這裡,解決了二件事
但是到這裡思考後隨即想到,按照PubNub範例的寫法
pubnub = new PubNub(pnConfiguration);
pubnub.SubscribeCallback += (sender, e) =>
{
SubscribeEventEventArgs mea = e as SubscribeEventEventArgs;
if (mea.Status != null)
{
if (mea.Status.Category.Equals(PNStatusCategory.PNConnectedCategory)) {
waitForConnect = true;
}
}
if (mea.MessageResult != null)
{
Debug.Log(" --- MESSAGE: ");
Dictionary<string, object> msg = mea.MessageResult.Payload as Dictionary<string, object>;
Debug.Log(string.Format("Channel: {0}, Sender: {1}, Content: {2}", mea.MessageResult.Channel, msg["sender"].ToString(), msg["content"].ToString()));
}
if (mea.PresenceEventResult != null)
{
Debug.Log(" --- PRESENCE: ");
Debug.Log(string.Format("Channel: {0}, Occupancy: {1}, Event: {2}", mea.PresenceEventResult.Channel, mea.PresenceEventResult.Occupancy, mea.PresenceEventResult.Event));
}
};
也就是它直接給了一個Callback,當有事件回來時就會反應。那底層肯定有個不停在聆聽事件是否有發生的機制,而這個機制如果不是用gRPC,那大概就又是tcp。也就是雖然從概念層去看相當的美好,當從實作層去看,是避不開雙向一直連線的機制。
回到單純的gRPC所實現的rpc,和利用pubsub概念的PubNub,其實還是有些不同。PubSub的概念裡,包裝並處理了事件保留和回送的機制,而單純的rpc,在不自己加功能的情況下,是沒有這些功能的,至於配對中這樣的機制到底有沒有必要,只能說簡易的配對應該不需要,但反正可以用,日後也可能會有相當適合的場合,再加上每個月開發的quota不少,就試試看吧。至於它一直保持連線這件事,反正是連到PubNub的server,又是合理的開發使用,相信也沒有什麼大問題。
但不論是純gRPC或是現有的PubNub,接下來稍微頭疼的是要利用golang進行server的撰寫。過往的開發中,利用golang的時間應該沒有超過10小時,看的懂80%,但要自己寫,就沒有什麼把握,趁著有空時來回顧一下過往鐵人賽golang相關的文章,應該會有不少幫助。